local windowFocusWatcher = {}

-- Internal state
local watcherTimer = nil
local lastWindowId = nil
local callbacks = {} -- List of registered callback functions

-- Register a new callback
function windowFocusWatcher.addCallback(fn)
	if type(fn) == "function" then
		table.insert(callbacks, fn)
	end
end

-- Remove a specific callback (by reference)
function windowFocusWatcher.removeCallback(fn)
	for i, cb in ipairs(callbacks) do
		if cb == fn then
			table.remove(callbacks, i)
			break
		end
	end
end

-- Clear all registered callbacks
function windowFocusWatcher.clearCallbacks()
	callbacks = {}
end

-- Internal function to invoke all registered callbacks
local function onWindowFocusChanged(win)
	for _, cb in ipairs(callbacks) do
		-- Use pcall to safely invoke each callback (prevents crash on error)
		pcall(cb, win)
	end
end

-- Start the window focus watcher (if not already running)
function windowFocusWatcher.start()
	if watcherTimer then
		return
	end

	lastWindowId = nil

	watcherTimer = hs.timer.doEvery(0.2, function()
		local win = hs.window.frontmostWindow()
		if not win or not win:id() then
			return
		end

		local winId = win:id()
		if winId ~= lastWindowId then
			lastWindowId = winId
			onWindowFocusChanged(win)
		end
	end)
end

-- Stop the watcher and reset state
function windowFocusWatcher.stop()
	if watcherTimer then
		watcherTimer:stop()
		watcherTimer = nil
	end
	lastWindowId = nil
end

return windowFocusWatcher
